#include <iostream>
#include "mgr/MsgSender.h"
#include "lib_json/json.h"
#include "tool/Utility.h"
#include "tool/Proto.h"
#include "mgr/LogMgr.h"

int MsgSender::Init(const std::string& conf_file) {
	Json::Value root;
	if (!Utility::LoadJson(conf_file, root)) return -1;
	this->m_svrip = root["svrip"].asString();
	this->m_svrport = root["svrport"].asInt();
#ifdef _WIN32
	WSADATA  wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
		std::cout << "WSAStartup Fail:" << GetLastError() << std::endl;
		return 1;
	}
#endif

#ifdef _WIN32
	m_Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	if (m_Socket == INVALID_SOCKET)
	{
		closesocket(m_Socket);
		m_Socket = INVALID_SOCKET;
		std::cout << "Socket Create Fail" << std::endl;
		return 2;
	}

	const char* ip = this->m_svrip.c_str();
	int port = this->m_svrport;
	m_RemoteAddress.sin_family = AF_INET;
	m_RemoteAddress.sin_port = htons(port);
	m_RemoteAddressLen = sizeof(m_RemoteAddress);
	inet_pton(AF_INET, ip, &m_RemoteAddress.sin_addr);
#else
    m_Socket = socket(AF_INET, SOCK_DGRAM, 0);
    if(m_Socket < 0)
    {
        std::cout << "Socket Create Fail" << std::endl;
        return 2;
    }

    bzero(&m_RemoteAddress, sizeof(m_RemoteAddress));

    m_RemoteAddress.sin_family = AF_INET;
    m_RemoteAddress.sin_port = htons(this->m_svrport);
    m_RemoteAddress.sin_addr.s_addr = inet_addr(this->m_svrip.c_str());
#endif

	return 0;
}

void MsgSender::Run() {
	m_thread = std::thread(&MsgSender::_Run, this);
// 先不定死CPU 看看啥情况
// #ifdef LINUX
// 	cpu_set_t cpuset;
 
//     CPU_ZERO(&cpuset);
// 	// TODO  如果绑定CPU 还需要获取总CPU个数
//     CPU_SET(41, &cpuset);
 
//     int rc =pthread_setaffinity_np(m_thread.native_handle(),sizeof(cpu_set_t), &cpuset);
 
//     if (rc != 0) {
//       std::cerr << "Error calling pthread_setaffinity_np: " << rc << "\n";
//     }
// #endif
}

// TODO 需要知道休息时间 尽量不要堆积或者塞满!
void MsgSender::_Run(){
	while (!m_exit)
	{
		std::string msg;
        bool ret = m_msgs.Pop(msg);
		if(ret){
			// 进行发送
			this->SendMsg(msg);
		}
		std::this_thread::sleep_for(std::chrono::milliseconds(2));
	}
}

void MsgSender::Push(const std::string& msg){
	m_msgs.Push(msg);
}

void MsgSender::SendMsg(const std::string& msg){
#ifdef _WIN32
	int sendLen = sendto(m_Socket, msg.c_str(), msg.length() + 1, 0, (sockaddr*)&m_RemoteAddress, m_RemoteAddressLen);
	if (sendLen < 0)
	{
		std::cout << "Udp Msg Send Fail :" << WSAGetLastError() << std::endl;
	}
	else {
		// std::cout << "Worker No." << this->m_id << "Udp Msg Send Success" << std::endl;
	}
#else
	int sendLen = sendto(m_Socket,  msg.c_str(), msg.length() + 1, 0, (struct sockaddr*)&m_RemoteAddress, sizeof(m_RemoteAddress));
	if(sendLen < 0){
		LOG_ERROR("Udp Msg Send Fail")
	}	
	else{
		// std::cout << "Worker No." << this->m_id << "Udp Msg Send Success" << std::endl;
	}
#endif
}